// • 进程间通信介绍
// • 掌握匿名命名管道原理操作
// • 编写进程池
// • 掌握共享内存
// • 了解消息队列
// • 了解信号量
// • 理解内核管理IPC资源的⽅式，了解C实现多态

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include<sys/stat.h>
#include <errno.h>
#include <fcntl.h> 
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while(0)
// 功能:创建⼀⽆名管道
// 原型
// int pipe(int fd[2]);
// 参数
// fd：⽂件描述符数组,其中fd[0]表⽰读端, fd[1]表⽰写端
// 返回值:成功返回0，失败返回错误代码


//从键盘读取数据，写⼊管道，读取管道，写到屏幕
// int main()
// {
//     int fds[2];
//     char buf[100];
//     int len;

//     if(pipe(fds) == -1)
//     {
//         //创建失败
//         perror("make pipe");
//         exit(1);
//     }

//     //read from stdin
//     while(fgets(buf, 100, stdin))
//     {
//         len = strlen(buf);

//         //write into pipe
//         //write 函数是一个系统调用，用于向文件描述符指向的文件、设备、管道等写入数据
//         if(write(fds[1], buf, sizeof(buf)) != len)
//         {
//             perror("write into pipe");
//             break;
//         }
//         //数据已经进入管道，此时清空buffer
//         memset(buf, 0x00, sizeof(buf));

//         //read from pipe
//         if((len = read(fds[0], buf, sizeof(buf)) == -1))
//         {
//             perror("read form pipe");
//             break;
//         }
//     }

// }

//检验父子进程间的管道通信
// int main(int argc, char* argv[])
// {
//     int pipefds[2];
//     if(pipe(pipefds) == -1)
//         ERR_EXIT("pipe error");

//     //管道创建完毕，开始创建进程
//     pid_t pid = fork();
//     if(pid < 0)
//         ERR_EXIT("fork errro");

//     if(pid == 0)
//     {
//         //子进程
//         close(pipefds[0]);//关闭读段，仅写
//         char buf[20] = "hello my g";
//         write(pipefds[1], buf, sizeof(buf));
//         //关闭写端，防止泄露
//         close(pipefds[1]);
//         //退出子进程
//         exit(EXIT_SUCCESS);
//     }
    

//     //父进程
//     close(pipefds[1]);//关闭写端
//     char buff[20] = {0};//全部置零 -- 防止垃圾数据干扰最后结果
//     read(pipefds[0], buff, sizeof(buff));
//     printf("buff = %s\n", buff);

//     return 0;

// }


//命名管道

// int main(int argc, char* argv[])
// {
//     if (mkfifo("p2", 0664) == -1) {
//         perror("mkfifo failed");  // 输出错误原因（如文件已存在、权限不足等）
//         exit(1);
//     }
// }



//读取文件，写入管道
// int main(int argc, char* argv[])
// {
//     mkfifo("tp", 0664);
//     int infd;
//     infd = open("asdfsdaf", O_RDONLY);
//     if(infd < 0) ERR_EXIT("open");

//     int outfd;
//     outfd = open("tp", O_WRONLY);
//     if(outfd < 0) ERR_EXIT("open");

//     char buf[1024];
//     int n;
//     while((n = read(infd, buf, 1024)) > 0)
//     {
//         write(outfd, buf, n);
//     }

//     close(infd);
//     close(outfd);

//     return 0;

// }


//读取管道，写入文件

int main(int argc, char* argv[])
{
    int outfd;
    outfd = open("aa.bak", O_TRUNC | O_WRONLY | O_CREAT);
    if(outfd == -1) ERR_EXIT("open");

    int infd;
    infd = open("tp", O_RDONLY);
    if(infd == -1) ERR_EXIT("open");

    int n;
    char buf[1024];
    while((n = read(infd, buf, 1024)) > 0)
    {
        write(outfd, buf, n);
    }

    close(infd);
    close(outfd);
    unlink("tp");//把管道断开

    return 0;
}






